//
//  OpenSDK_ReqDataGenerator.m
//  OpenSDK
//
//  Created by wyht－ios－dev on 16/3/18.
//  Copyright © 2016年 WYHT. All rights reserved.
//

#import "OpenSDK_ReqDataGenerator.h"
#import "OpenSDK_DataManager.h"
#import "OpenSDK_DataKeys.h"
#import "OpenSDK_JsonUtil.h"
#import "OpenSDK_EncryptUtil.h"
#import "OpenSDK_LocalRecord.h"
#import "OpenSDK_HttpUtil.h"
#import "OpenSDK_MD5.h"
#import <Y2Common/Y2Common.h>

@implementation OpenSDK_ReqDataGenerator
{
    NSMutableDictionary *sdkParametersLocalRecord;
}

static OpenSDK_ReqDataGenerator *instance = nil;

+(instancetype) getInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

-(void) restoreSDKParameters:(NSMutableDictionary *)sdkParameter
{
    sdkParametersLocalRecord=sdkParameter;
}

-(NSMutableDictionary *) getSDKParameters
{
    return sdkParametersLocalRecord;
}

+(NSString *) generateResetPasswordDataWithPhone:(NSString *)phoneNumber password:(NSString *)password randomPassword:(NSString *)randomPassword {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    NSString *localCountryCode=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_COUNTRY_CODE];
    if(localCountryCode!=nil) {
        [data setObject:localCountryCode forKey:OpenSDK_S_COUNTRY_INFO];
    }
    [data setObject:phoneNumber forKey:OpenSDK_S_MOBILE_ACCOUNT];
    [data setObject:password forKey:OpenSDK_S_NEW_PASSWORD];
    [data setObject:randomPassword forKey:OpenSDK_S_SECURITY];
    return [self generateDataByDictionary:data];
}

+(NSString *) generateRegistrationDataWithPhone:(NSString *)phoneNumber password:(NSString *)password randomPassword:(NSString *)randomPassword {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    NSString *localCountryCode=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_COUNTRY_CODE];
    if(localCountryCode!=nil) {
        [data setObject:localCountryCode forKey:OpenSDK_S_COUNTRY_INFO];
    }
    [data setObject:phoneNumber forKey:OpenSDK_S_MOBILE_ACCOUNT];
    [data setObject:password forKey:OpenSDK_S_PASSWORD];
    [data setObject:randomPassword forKey:OpenSDK_S_SECURITY];
    [data setObject:[Y2DeviceInfo getDeviceID] forKey:OpenSDK_S_MOBILE_RANDOM_PASSWORD_ID];
    return [self generateDataByDictionary:data];
}

+(NSString *) generateRegistrationDataWithName:(NSString *)userName password:(NSString *)password
{
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:userName forKey:OpenSDK_S_EMAIL];
    [data setObject:userName forKey:OpenSDK_S_USERNAME];
    [data setObject:password forKey:OpenSDK_S_PASSWORD];

    return [self generateDataByDictionary:data];
}

+(NSString *) generateBindingDataPhoneNumber:(NSString *)phoneNumber
                                    password:(NSString *)password
                              randomPassword:(NSString *)randomPassword
                                      openId:(NSString *)openId
                                       token:(NSString *)token
                                    platform:(NSString *)platform{
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    NSString *localCountryCode=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_COUNTRY_CODE];
    if(localCountryCode!=nil) {
        [data setObject:localCountryCode forKey:OpenSDK_S_COUNTRY_INFO];
    }
    [data setObject:phoneNumber forKey:OpenSDK_S_MOBILE_ACCOUNT];
    if (password != nil && password.length > 0) {
        [data setObject:password forKey:OpenSDK_S_PASSWORD];
    }
    [data setObject:platform forKey:OpenSDK_S_PLATFORM_ID];
    [data setObject:randomPassword forKey:OpenSDK_S_SECURITY];
    [data setObject:openId forKey:OpenSDK_S_OPEN_ID];
    [data setObject:token forKey:OpenSDK_S_TOKEN];
    [data setObject:OpenSDK_S_DYNAMIC forKey:OpenSDK_S_OAUTH_TYPE];
    [data setObject:[Y2DeviceInfo getDeviceID] forKey:OpenSDK_S_MOBILE_RANDOM_PASSWORD_ID];
    
    return [self generateDataByDictionary:data];
}

+(NSString *) generateBindingDataWithName:(NSString *)userName password:(NSString *)password
{
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:userName forKey:OpenSDK_S_EMAIL];
    [data setObject:userName forKey:OpenSDK_S_USERNAME];
    [data setObject:password forKey:OpenSDK_S_PASSWORD];
    NSString *userToken = [[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_USERTOKEN];
    NSString *openID = [[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_OPENID];
    [data setObject:openID forKey:OpenSDK_S_OPEN_ID];
    [data setObject:userToken forKey:OpenSDK_S_TOKEN];
    [data setObject:OpenSDK_S_ACCOUNT forKey:OpenSDK_S_OAUTH_TYPE];
    
    return [self generateDataByDictionary:data];
}

+(NSString *) generateBindingDataWithOtherSDK
{
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    NSString *userToken = [[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_USERTOKEN];
    NSString *openID = [[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_OPENID];
    [data setObject:openID forKey:OpenSDK_S_OPEN_ID];
    [data setObject:userToken forKey:OpenSDK_S_TOKEN];
    if ([[OpenSDK_ReqDataGenerator getInstance] getSDKParameters]) {
        [data addEntriesFromDictionary:[[OpenSDK_ReqDataGenerator getInstance] getSDKParameters]];
    }
    
    return [self generateDataByDictionary:data];
}

+(NSString *) generateUserCheckDataWithPhoneNumber:(NSString *)phoneNumber
                                          password:(NSString *)password {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    NSString *localCountryCode=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_COUNTRY_CODE];
    if(localCountryCode!=nil) {
        [data setObject:localCountryCode forKey:OpenSDK_S_COUNTRY_INFO];
    }
    [data setObject:OpenSDK_S_MOBILE forKey:OpenSDK_S_OAUTH_TYPE];
    [data setObject:phoneNumber forKey:OpenSDK_S_MOBILE_ACCOUNT];
    [data setObject:password forKey:OpenSDK_S_PASSWORD];
    
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateUserCheckDataWithLoginToken:(NSString *)token {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    NSString *localCountryCode=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_COUNTRY_CODE];
    if(localCountryCode!=nil) {
        [data setObject:localCountryCode forKey:OpenSDK_S_COUNTRY_INFO];
    }
    [data setObject:OpenSDK_S_ONE_KEY forKey:OpenSDK_S_OAUTH_TYPE];
    [data setObject:token forKey:@"loginToken"];
    
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateUserCheckDataWithPhoneNumber:(NSString *)phoneNumber
                                    randomPassword:(NSString *)randomPassword {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    NSString *localCountryCode=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_COUNTRY_CODE];
    if(localCountryCode!=nil) {
        [data setObject:localCountryCode forKey:OpenSDK_S_COUNTRY_INFO];
    }
    [data setObject:OpenSDK_S_DYNAMIC forKey:OpenSDK_S_OAUTH_TYPE];
    [data setObject:phoneNumber forKey:OpenSDK_S_MOBILE_ACCOUNT];
    [data setObject:randomPassword forKey:OpenSDK_S_SECURITY];
    [data setObject:[Y2DeviceInfo getDeviceID] forKey:OpenSDK_S_MOBILE_RANDOM_PASSWORD_ID];
    [data setObject:@"2" forKey:@"login_version"];
    
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateSMSDataWithPhoneNumber:(NSString *)phoneNumber smsType:(NSString *)smsType {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    NSString *localCountryCode=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_COUNTRY_CODE];
    if(localCountryCode!=nil) {
        [data setObject:localCountryCode forKey:OpenSDK_S_COUNTRY_INFO];
    }
    [data setObject:phoneNumber forKey:OpenSDK_S_MOBILE_ACCOUNT];
    [data setObject:smsType forKey:OpenSDK_S_TARGET];
    [data setObject:[Y2DeviceInfo getDeviceID] forKey:OpenSDK_S_MOBILE_RANDOM_PASSWORD_ID];
    
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateCheckRealNameDataWithOpenID:(NSString *)openID
                                            token:(NSString *)token {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:openID forKey:OpenSDK_S_OPEN_ID];
    [data setObject:token forKey:OpenSDK_S_TOKEN];
    
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateRealNameDataWithOpenID:(NSString *)openID
                                       token:(NSString *)token
                                    realName:(NSString *)realName
                                  cardNumber:(NSString *)cardNumber
                                  phoneNumber:(NSString *)phoneNumber
                                  security:(NSString *)security {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:openID forKey:OpenSDK_S_OPEN_ID];
    [data setObject:token forKey:OpenSDK_S_TOKEN];
    [data setObject:realName forKey:OpenSDK_S_REAL_NAME];
    [data setObject:@"IDCard" forKey:OpenSDK_S_CARD_TYPE];
    [data setObject:cardNumber forKey:OpenSDK_S_CARD_NUMBER];
    // 手机号和验证，选填
    if (phoneNumber != nil && phoneNumber.length > 0) {
        NSString *localCountryCode=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_COUNTRY_CODE];
        if (localCountryCode!=nil) {
            [data setObject:localCountryCode forKey:OpenSDK_S_COUNTRY_INFO];
        }
        [data setObject:phoneNumber forKey:OpenSDK_S_MOBILE_ACCOUNT];
        [data setObject:[Y2DeviceInfo getDeviceID] forKey:OpenSDK_S_MOBILE_RANDOM_PASSWORD_ID];
    }
    if (security != nil && security.length > 0) {
        [data setObject:security forKey:OpenSDK_S_SECURITY];
    }
    
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateUserCheckDataWithName:(NSString *)userName password:(NSString *)password
{
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:OpenSDK_S_ACCOUNT forKey:OpenSDK_S_OAUTH_TYPE];
    [data setObject:userName forKey:OpenSDK_S_USERNAME];
    [data setObject:password forKey:OpenSDK_S_PASSWORD];
    
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateUserCheckDataWithToken:(NSString *)token openID:(NSString *)openID
{
    NSMutableDictionary *data=[[NSMutableDictionary alloc] init];
    [data setObject:[[OpenSDK_DataManager getInstance] appID] forKey:OpenSDK_S_GRANT_APP];
    [data setObject:token forKey:OpenSDK_S_TOKEN];
    [data setObject:openID forKey:OpenSDK_S_OPEN_ID];
    
    //适配绑定（后面需要改）
    [data setObject:[Y2DeviceInfo getDeviceID] forKey:OpenSDK_S_ACTIVE_BIND_ID];
    //以设备方式绑定
    [data setObject:@"device" forKey:OpenSDK_S_ACTIVE_BIND_TYPE];
    [data setObject:@"2.0" forKey:@"opensdk_version"];
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateCreateOrderDataWithPayInfo:(OpenSDK_PayInfo *)payInfo {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    if (payInfo.productID) {
        [data setObject:payInfo.productID forKey:OpenSDK_S_PRODUCTID];
    }
    if (payInfo.orderAmount) {
        [data setObject:payInfo.orderAmount forKey:OpenSDK_S_PRODUCT_AMOUNT];
    }
    if (payInfo.productName) {
        [data setObject:payInfo.productName forKey:OpenSDK_S_PRODUCT_NAME ];
    }
    if (payInfo.appData) {
        [data setObject:payInfo.appData forKey:OpenSDK_S_APPDATA];
    }
    if (payInfo.currency) {
        [data setObject:payInfo.currency forKey:OpenSDK_S_CURRENCY];
    }
    if (payInfo.notifyUrl) {
        [data setObject:payInfo.notifyUrl forKey:OpenSDK_S_PAY_NOTIFYURL];
    }
    if (payInfo.tradeType) {
        [data setObject:payInfo.tradeType forKey:OpenSDK_S_TRADE_TYPE];
    }
    [data setObject:payInfo.uid forKey:OpenSDK_S_UID];
    [data setObject:[Y2DeviceInfo getDeviceID] forKey:OpenSDK_S_DEVICE_ID];
    [data setObject:payInfo.platform forKey:OpenSDK_S_PLATFORM];
    [data setObject:payInfo.payVersion forKey:OpenSDK_S_PLATFORM_VERSION];
    [data setObject:@"2.0" forKey:@"opensdk_version"];
    [data setObject:[OpenSDK_DataManager getInstance].currentAccount.token forKey:OpenSDK_TOKEN];
    [data setObject:[OpenSDK_DataManager getInstance].currentAccount.openId forKey:OpenSDK_S_OPEN_ID];
    return [self generateDataByDictionary:data];
}

+(NSString *) generateLogoutDataWithToken:(NSString *)token uid:(NSString *)uid
{
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:token forKey:OpenSDK_S_TOKEN];
    [data setObject:uid forKey:OpenSDK_S_OPEN_ID];

    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateQueryActiveCodeData:(NSString *) affect {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:affect forKey:OpenSDK_S_ACTIVE_AFFECT];
    
    return [self generateDataByDictionary:data];
}

+(NSString *) generateBindActiveCodeData:(NSString *) code {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:code forKey:OpenSDK_S_ACTIVE_CODE];
    
    return [self generateDataByDictionary:data];
}

+(NSString *) generateQuickLoginData
{
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:OpenSDK_S_TEMPORARY forKey:OpenSDK_S_OAUTH_TYPE];
    [data setObject:[OpenSDK_DataManager getTemporaryUserID] forKey:OpenSDK_S_TEMP_ID];
    
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateTmpLoginData:(NSString *)tmpId {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:OpenSDK_S_TEMPORARY forKey:OpenSDK_S_OAUTH_TYPE];
    if (tmpId != nil && tmpId.length > 0) {
        [data setObject:tmpId forKey:OpenSDK_S_TEMP_ID];
    }
    
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSString *) generateFindPasswordDataWithPhoneNumber:(NSString *) phoneNumber {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    NSString *localCountryCode=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_COUNTRY_CODE];
    if(localCountryCode!=nil) {
        [data setObject:localCountryCode forKey:OpenSDK_S_COUNTRY_INFO];
    }
    [data setObject:phoneNumber forKey:OpenSDK_S_MOBILE_ACCOUNT];
    return [self generateDataByDictionary:data];
}

+(NSString *) generateFindPasswordData:(NSString *) email {
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    [data setObject:email forKey:OpenSDK_S_USERNAME];
    return [self generateDataByDictionary:data];
}

+(NSString *) generateBindData {
    return [OpenSDK_ReqDataGenerator generateWebRealNameData];
}

+(NSString *) generateWebRealNameData {
    NSMutableDictionary *data=[[NSMutableDictionary alloc] init];
    [data setObject:[[OpenSDK_DataManager getInstance] appID] forKey:OpenSDK_S_GRANT_APP];
    [data setObject:[[OpenSDK_DataManager getInstance] channelID] forKey:OpenSDK_S_CHANNEL];
    //获取本地保存的id和token
    NSString *token=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_USERTOKEN];
    NSString *openID=[[OpenSDK_LocalRecord getInstance] getLocalValueForKey:OpenSDK_L_OPENID];
    if(openID!=nil)
        [data setObject:openID forKey:OpenSDK_S_OPEN_ID];
    if(token!=nil)
        [data setObject:token forKey:OpenSDK_S_TOKEN];
    
    NSMutableArray *parametersArray = [[NSMutableArray alloc] init];
    for (NSString *key in [data allKeys]) {
        id value = [data objectForKey:key];
        if ([value isKindOfClass:[NSString class]]) {
            [parametersArray addObject:[NSString stringWithFormat:@"%@=%@",key,value]];
        }
    }
    
    return [parametersArray componentsJoinedByString:@"&"];
}

+(NSString *) generateInitData
{
    NSMutableDictionary *data=[self generateInitDataWithInfo];
    return [self generateDataByDictionary:data signEncryption:ReqDataSignEncryptionMD5];
}

+(NSMutableDictionary *) generateDeviceInfo
{
    NSMutableDictionary *data=[[NSMutableDictionary alloc] init];
    [data setObject:OpenSDK_S_MY_DEVICE forKey:OpenSDK_S_DEVICE_TYPE];
    [data setObject:[Y2DeviceInfo getDeviceID] forKey:OpenSDK_S_DEVICE_ID];
    return data;
}

//产生带oauth_app和channel的公用信息体
+(NSMutableDictionary *) generateInitDataWithInfo
{
    NSMutableDictionary *data=[self generateDeviceInfo];
    [data setObject:[[OpenSDK_DataManager getInstance] appID] forKey:OpenSDK_S_GRANT_APP];
    [data setObject:[[OpenSDK_DataManager getInstance] channelID] forKey:OpenSDK_S_CHANNEL];
    
    //适配绑定（后面需要改）
    [data setObject:[Y2DeviceInfo getDeviceID] forKey:OpenSDK_S_ACTIVE_BIND_ID];
    //以设备方式绑定
    [data setObject:@"device" forKey:OpenSDK_S_ACTIVE_BIND_TYPE];
    
    return data;
}

+(NSString *) generateDataByDictionary:(NSMutableDictionary *) data{
    return [OpenSDK_ReqDataGenerator generateDataByDictionary:data signEncryption:ReqDataSignEncryptionRSA];
}

+(NSString *) generateDataByDictionary:(NSMutableDictionary *) data
                        signEncryption:(ReqDataSignEncryption)encryption
{
    //添加time字段
    UInt64 recordTime = [[NSDate date] timeIntervalSince1970]*1000;
    NSString *timeSp = [NSString stringWithFormat:@"%lld", recordTime];
    [data setObject:timeSp forKey:@"time"];
    NSMutableDictionary *tmpDic = nil;
    if (encryption == ReqDataSignEncryptionRSA){
        tmpDic = [[NSMutableDictionary alloc] init];
        NSString *tmpAppID=[[[OpenSDK_DataManager getInstance] appID] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        [tmpDic setObject:[OpenSDK_HttpUtil urlEncode:[OpenSDK_EncryptUtil generateRSAResultByData:data]] forKey:@"q"];
        [tmpDic setObject:tmpAppID forKey:@"v"];
        //转换格式
        NSMutableArray *parametersArray = [[NSMutableArray alloc] init];
        for (NSString *key in [tmpDic allKeys]) {
            id value = [tmpDic objectForKey:key];
            if ([value isKindOfClass:[NSString class]]) {
                [parametersArray addObject:[NSString stringWithFormat:@"%@=%@",key,value]];
            }
        }
        return [parametersArray componentsJoinedByString:@"&"];
        
    }else{
        tmpDic = [data mutableCopy];
        tmpDic[@"sign"] = [OpenSDK_EncryptUtil generateMD5ResultByData:data];
        NSMutableArray *parametersArray = [[NSMutableArray alloc] init];
        for (NSString *key in [tmpDic allKeys]) {
            id value = [tmpDic objectForKey:key];
            if ([value isKindOfClass:[NSString class]]) {
                [parametersArray addObject:[NSString stringWithFormat:@"%@=%@",key,[OpenSDK_HttpUtil urlEncode:value]]];
            }
        }
        return [parametersArray componentsJoinedByString:@"&"];
    }
    
}


@end
